﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Newtonsoft.Json;
using System.IO;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace FastTunnel_Config
{
    public partial class Form1 : Form
    {
        Config config;

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (File.Exists("myfile.txt"))
            {
                txt_File.Text = File.ReadAllText("myfile.txt", Encoding.Default);
            }
            OpenConfig();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (txt_webIp.Text == "" || txt_webName.Text == "" || txt_webport.Text == "")
            {
                MessageBox.Show("需要的信息尚未填写。。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                Webconfig webconfig = new Webconfig() { LocalIp = txt_webIp.Text.Trim(), LocalPort = ushort.Parse(txt_webport.Text.Trim()), SubDomain = txt_webName.Text.Trim() };
                string[] vs = { webconfig.SubDomain, webconfig.LocalIp, webconfig.LocalPort.ToString() };
                ls_webconfig.Items.Add(new ListViewItem(vs));
            }
            catch (Exception ex)
            {
                MessageBox.Show("填写的信息在转换时发生问题 请检查。。\n\n 端口只能为 [1-65535] \n\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (txt_webIp.Text == "" || txt_webName.Text == "" || txt_webport.Text == "")
            {
                MessageBox.Show("需要的信息尚未填写。。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                Webconfig webconfig = new Webconfig() { LocalIp = txt_webIp.Text.Trim(), LocalPort = ushort.Parse(txt_webport.Text.Trim()), SubDomain = txt_webName.Text.Trim() };
                ls_webconfig.SelectedItems[0].SubItems[0].Text = webconfig.SubDomain;
                ls_webconfig.SelectedItems[0].SubItems[1].Text = webconfig.LocalIp;
                ls_webconfig.SelectedItems[0].SubItems[2].Text = webconfig.LocalPort.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("填写的信息在转换时发生问题 请检查。。\n\n 端口只能为 [1-65535] \n\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (ls_webconfig.SelectedItems.Count > 0)
            {
                //有选中的设置..
                if (MessageBox.Show("您确定要删除选中的WEB穿透设置吗？", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    foreach (ListViewItem lvi in ls_webconfig.SelectedItems)
                    {
                        ls_webconfig.Items.Remove(lvi);
                    }
                }
            }
        }

        private void ls_webconfig_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ls_webconfig.SelectedItems.Count < 1)
            {
                return;
            }
            txt_webName.Text = ls_webconfig.SelectedItems[0].SubItems[0].Text;
            txt_webIp.Text = ls_webconfig.SelectedItems[0].SubItems[1].Text;
            txt_webport.Text = ls_webconfig.SelectedItems[0].SubItems[2].Text;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (txt_locIP.Text == "" || txt_locPort.Text == "" || txt_lsnPort.Text == "")
            {
                MessageBox.Show("需要的信息尚未填写。。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                SSHconfig sSHconfig = new SSHconfig() { LocalIp = txt_locIP.Text.Trim(), LocalPort = ushort.Parse(txt_locPort.Text.Trim()), RemotePort = ushort.Parse(txt_lsnPort.Text.Trim()) };
                string[] vs = { sSHconfig.RemotePort.ToString(), sSHconfig.LocalIp, sSHconfig.LocalPort.ToString() };
                ls_config.Items.Add(new ListViewItem(vs));
            }
            catch (Exception ex)
            {
                MessageBox.Show("填写的信息在转换时发生问题 请检查。。\n\n 端口只能为 [1-65535] \n\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (txt_locIP.Text == "" || txt_locPort.Text == "" || txt_lsnPort.Text == "")
            {
                MessageBox.Show("需要的信息尚未填写。。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                SSHconfig sSHconfig = new SSHconfig() { LocalIp = txt_locIP.Text.Trim(), LocalPort = ushort.Parse(txt_locPort.Text.Trim()), RemotePort = ushort.Parse(txt_lsnPort.Text.Trim()) };
                ls_config.SelectedItems[0].SubItems[0].Text = sSHconfig.RemotePort.ToString();
                ls_config.SelectedItems[0].SubItems[1].Text = sSHconfig.LocalIp;
                ls_config.SelectedItems[0].SubItems[2].Text = sSHconfig.LocalPort.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("填写的信息在转换时发生问题 请检查。。\n\n 端口只能为 [1-65535] \n\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (ls_config.SelectedItems.Count > 0)
            {
                //有选中的设置..
                if (MessageBox.Show("您确定要删除选中的TCP穿透设置吗？", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    foreach (ListViewItem lvi in ls_config.SelectedItems)
                    {
                        ls_config.Items.Remove(lvi);
                    }

                }
            }
        }

        private void ls_config_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ls_config.SelectedItems.Count > 0)
            {
                txt_lsnPort.Text = ls_config.SelectedItems[0].SubItems[0].Text;
                txt_locIP.Text = ls_config.SelectedItems[0].SubItems[1].Text;
                txt_locPort.Text = ls_config.SelectedItems[0].SubItems[2].Text;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                config.ClientSettings.Server.ServerAddr = txt_ServerIP.Text.Trim();
                config.ClientSettings.Server.ServerPort = ushort.Parse(txt_ServerPort.Text.Trim());

                config.ClientSettings.Webs = new Webconfig[ls_webconfig.Items.Count];
                config.ClientSettings.SSH = new SSHconfig[ls_config.Items.Count];

                for (int s = 0; s < ls_webconfig.Items.Count; s++)
                {
                    config.ClientSettings.Webs[s].SubDomain = ls_webconfig.Items[s].SubItems[0].Text;
                    config.ClientSettings.Webs[s].LocalIp = ls_webconfig.Items[s].SubItems[1].Text;
                    config.ClientSettings.Webs[s].LocalPort = ushort.Parse(ls_webconfig.Items[s].SubItems[2].Text);
                }

                for (int i = 0; i < ls_config.Items.Count; i++)
                {
                    config.ClientSettings.SSH[i].RemotePort = ushort.Parse(ls_config.Items[i].SubItems[0].Text.Trim());
                    config.ClientSettings.SSH[i].LocalIp = ls_config.Items[i].SubItems[1].Text.Trim();
                    config.ClientSettings.SSH[i].LocalPort = ushort.Parse(ls_config.Items[i].SubItems[2].Text.Trim());
                }

                File.WriteAllText(txt_File.Text, JsonConvert.SerializeObject(config, Formatting.Indented), Encoding.Default);
                File.WriteAllText("myfile.txt", txt_File.Text, Encoding.Default);

                MessageBox.Show("保存成功\n\n", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);

            }
            catch (Exception ex)
            {
                MessageBox.Show("保存设置失败。 \n\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void button9_Click(object sender, EventArgs e)
        {
            openFileDialog1.Title = "请选择 FastTunnel 配置文件 appsettings.json";
            openFileDialog1.FileName = "appsettings.json";
            openFileDialog1.Filter = "appsettings.json|appsettings.json";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                //MessageBox.Show(openFileDialog1.FileName);
                txt_File.Text = openFileDialog1.FileName;
                OpenConfig();
            }
        }

        void OpenConfig()
        {
            if (File.Exists(txt_File.Text))
            {
                config = JsonConvert.DeserializeObject<Config>(File.ReadAllText(txt_File.Text, Encoding.Default));
            }
            else
            {
                config = new Config();
                config.Logging.LogLevel.Default = "Trace";
                config.Logging.LogLevel.Microsoft = "Warning";
                config.Logging.LogLevel.MicrosoftHostingLifetime = "Information";

                config.ClientSettings.Server.ServerAddr = "127.0.0.1";
                config.ClientSettings.Server.ServerPort = 1271;

                config.ClientSettings.Webs = new Webconfig[1];
                config.ClientSettings.Webs[0].LocalIp = "127.0.0.1";
                config.ClientSettings.Webs[0].LocalPort = 8090;
                config.ClientSettings.Webs[0].SubDomain = "test.test.cc";

                config.ClientSettings.SSH = new SSHconfig[1];

                config.ClientSettings.SSH[0].LocalIp = "127.0.0.1";
                config.ClientSettings.SSH[0].LocalPort = 3389;
                config.ClientSettings.SSH[0].RemotePort = 63389;
            }

            txt_ServerIP.Text = config.ClientSettings.Server.ServerAddr;
            txt_ServerPort.Text = config.ClientSettings.Server.ServerPort.ToString();

            ls_config.Items.Clear();
            ls_webconfig.Items.Clear();

            foreach (var bb in config.ClientSettings.Webs)
            {
                string[] vs = { bb.SubDomain, bb.LocalIp, bb.LocalPort.ToString() };
                ls_webconfig.Items.Add(new ListViewItem(vs));
            }

            foreach (var aa in config.ClientSettings.SSH)
            {
                string[] vs = { aa.RemotePort.ToString(), aa.LocalIp, aa.LocalPort.ToString() };
                ls_config.Items.Add(new ListViewItem(vs));
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (txt_File.Text == "")
            {
                MessageBox.Show("请先打开配置文件.\n\n程序将会启动这个配置所在目录的 FastTunnel.Client.exe", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string stt = Regex.Replace(txt_File.Text, "appsettings.json", "FastTunnel.Client.exe", RegexOptions.IgnoreCase);
            try
            {
                Process proc = Process.Start(stt);
                button2.Enabled = false;
                proc.EnableRaisingEvents = true;
                proc.Exited += Proc_Exited;
            }
            catch (Exception ex)
            {
                MessageBox.Show("配置文件目录下未找到 FastTunnel.Client.exe\n\n" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        }

        private void Proc_Exited(object sender, EventArgs e)
        {
            if (cbx_auto.Checked)
            {
                button2_Click(sender, e);
            }
            else
            {
                button2.Enabled = true;
            }
        }
    }

    public struct Config
    {
        public Logging Logging;
        public ClientSettingsEx ClientSettings;
    }

    public struct Logging
    {
        public LogLevel LogLevel;
    }

    public struct LogLevel
    {
        public string Default;
        public string Microsoft;
        [JsonProperty(PropertyName = "Microsoft.Hosting.Lifetime")]
        public string MicrosoftHostingLifetime;

    }

    public struct ClientSettingsEx
    {
        public WebServer Server;
        public Webconfig[] Webs;
        public SSHconfig[] SSH;
    }

    public struct WebServer
    {
        public string ServerAddr;
        public ushort ServerPort;
    }

    public struct Webconfig
    {
        public string LocalIp;
        public ushort LocalPort;
        public string SubDomain;
    }

    public struct SSHconfig
    {
        public string LocalIp;
        public ushort LocalPort;
        public ushort RemotePort;
    }
}
